home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / vmed.arc / VMMGR.CCC < prev    next >
Encoding:
Text File  |  1985-12-03  |  7.5 KB  |  254 lines

  1. /* VMMGR/CCC
  2.  *    virtual memory tables and RAM management routines
  3.  *
  4.  *    Copyright 1983, 1984 by Jim Kyle - All Rights Reserved
  5.  *    Licensed for individual non-commercial use only.
  6.  *
  7.  *         created:    November 16, 1983 - Jim Kyle
  8.  *         changed:    November 26, 1983 - Jim Kyle
  9.  *    last changed:    March 3, 1984 - Jim Kyle
  10.  */
  11.  
  12. /*    data global to this module:
  13.  *        first three arrays serve as a structure:
  14.  *            struct vmtable {
  15.  *                int        Secno;
  16.  *                char    *Slot;
  17.  *                int        Lru;
  18.  *            } Vmtbl[NSLOTS];
  19.  */
  20. int        Secno[NSLOTS];        /* Sector Nbr for slot */ 
  21. char    *Slot[NSLOTS];        /* Buffer address for slot */
  22. int        Lru[NSLOTS];        /* Usage Counter for slot */
  23.  
  24. int        Cslot;                /* Current Slot's index */
  25. int        Frstfs;                /* First Free Slot index */
  26. FILE    *Tmpfp;                /* fp for VM temp file */
  27. static int        Free;        /* Head of diskfile ASL */
  28. int        Lstsec;                /* Last Sector Nbr used */
  29. int        *Bcptr;                /* Ptr to curr Byte Count */
  30. int        *Nxptr;                /* Ptr to Next link, curr */
  31. int        Curr;                /* Current-block number */
  32.  
  33. int        *Pvptr;                /* Ptr to Prev link, curr */
  34. int        *Lcptr;                /* Ptr to curr Line ctr */
  35. char    *Dbptr;                /* Ptr to curr Data base */
  36. int        Dbndx;                /* Relative to Dbptr */
  37. int        Flcb;                /* First line curr block */
  38. int        Llcb;                /* Last line current block */
  39. int        Cur_ln;                /* Current line's number */
  40. int        Lltf;                /* Last line total file */
  41. char    Bfrs[BFRSZ];        /* The slots themselves */
  42. #option    ZVAR    ON
  43. int        Iflag;                /* 0 until tempfile created */
  44. #option    ZVAR    OFF
  45.  
  46. /*
  47.  *    vm_init() must be called before any use of the VM
  48.  *    routines, to properly initialize all tables, counts,
  49.  *    and pointers.
  50.  *
  51.  *    It will return OK if successful, or ERR if not.
  52.  */
  53. vm_init()                /* initialize the tables */
  54. {    int i;
  55.     char *j;
  56.     j = Bfrs;
  57.     for (i=0; i < NSLOTS; ++i) {
  58.         Slot[i] = j;        /* set in addresses */
  59.         Lru[i] = Secno[i] = *(j+1) = *j = 0;
  60.         j += BLKSIZ;
  61.         }
  62.     if (Iflag == 0)
  63.         Tmpfp = fopen("VM/TMP","w");    /* create tempfile */
  64.     Iflag = EOF;                        /* set Iflag */
  65.         /* zero out counters and pointers */
  66.     Flcb = Llcb = Lltf = Frstfs = Free = Dbndx = 0;
  67.     Lstsec = SECBEG;        /* no sectors used yet */
  68. /* changed from vm_get(0) on 3-3-84 - jk */
  69.     return(go_top());        /* start sec 0, slot 0 */
  70. }
  71.  
  72. /*
  73.  *    vm_get() makes the block identified by its single
  74.  *    argument the "current block" and sets all pointers
  75.  *    accordingly. Paging to-from disk file is automatic.
  76.  *
  77.  *    Return value is OK if successful, else ERR.
  78.  */
  79. vm_get(sec)    int sec;    /* make 'sec' Current block */
  80. {    Cslot = findslot(sec);        /* get it into RAM */
  81.     if (Cslot < 0)
  82.         return(ERR);
  83.     Bcptr = Slot[Cslot];    /* ptr to curr byte count */
  84.     Curr = sec;                /* identify current block */
  85.     Nxptr = Bcptr + 1;        /* ptr to next block */
  86.     Pvptr = Nxptr + 1;        /* ptr to prev block */
  87.     Lcptr = Pvptr + 1;        /* ptr to line count */
  88.     Dbptr = Lcptr + 1;        /* base of data area */
  89.     return(OK);
  90. }
  91.  
  92. /*
  93.  *    findslot() gets the referenced block into one of the
  94.  *    RAM slots, swapping in or out as required.
  95.  *
  96.  *    Return value is the slot number if successful, or
  97.  *    ERR if any error occurs.
  98.  */
  99. findslot(sec)    int sec;    /* returns slotndx or ERR */
  100. {    int i,j,k;
  101.     for (i=0; i<Frstfs; ++i)    /* bump usage count */
  102.         ++Lru[i];
  103.     for (i=0; i<Frstfs; ++i)    /* already here? */
  104.         if (sec == Secno[i]) {
  105.             Lru[i] = 0;            /* yes, clear LRU */
  106.             return(i);            /* and get out */
  107.             }
  108.     if (Frstfs < NSLOTS)        /* no, is one free? */
  109.         k = Frstfs++;            /* yes, take it */
  110.     else {                        /* no, free one */
  111.         j = *Lru;
  112.         k = 0;
  113.         for (i=1; i<NSLOTS; ++i)
  114.             if (j < Lru[i]) {    /* find oldest */
  115.                 j = Lru[i];
  116.                 k = i;
  117.                 }
  118.         if (free_slot(k,Secno[k]))
  119.             return(vm_err("free_slot write"));
  120.         }
  121.     return(fill_slot(k,sec)==OK ? k : ERR);
  122. }
  123.  
  124. /*
  125.  *    free_slot() moves the referenced slot's contents to
  126.  *    the referenced block on disk. It is called only by
  127.  *    findslot().
  128.  */
  129. free_slot(slt,sec)    int slt,sec;    /* move to disk */
  130. {    int i,j,*k;
  131.     k = Slot[slt];        /* ptr to buffer space */
  132.     if (*k & DIRTY)
  133.         *k &= CLEAN;    /* clean up before writing */
  134.     else
  135.         return(OK);        /* no need to write out */
  136.     /* seek to sec */
  137.     if (sec_seek(Tmpfp,sec))
  138.         return(vm_err("free_slot seek"));
  139.     /* write BLKSIZ bytes from Slot buffer */
  140.     return((fwrite(Tmpfp,k,BLKSIZ)==BLKSIZ) ? OK : ERR);
  141. }
  142.  
  143. /*
  144.  *    fill_slot() moves the content of the referenced block
  145.  *    into the referenced slot. It is called only by
  146.  *    findslot().
  147.  */
  148. fill_slot(slt,sec)    int slt,sec;    /* move fm disk */
  149. {    int i,j,*k;
  150.     k = Slot[slt];        /* ptr to buffer space */
  151.     Secno[slt] = sec;    /* identify the sector */
  152.     Lru[slt] = 0;        /* clear usage counter */
  153.     if (sec > Lstsec) {        /* extending disk, no read */
  154.         Lstsec = sec;
  155.         *k++ = BHAD;            /* initial byte count */
  156.         for (i=1; i++ < 512;)
  157.             *k++ = 0;            /* zero rest of slot */
  158.         return(OK);
  159.         }
  160.     /* must seek to sec */
  161.     if (sec_seek(Tmpfp,sec))
  162.         return(vm_err("fill_slot seek"));
  163.     /* then read BLKSIZ bytes to Slot buffer */
  164.     i = fread(Tmpfp,k,BLKSIZ);
  165.     if (i < 1)
  166.         return (i ? ERR : EOF);
  167.     return(OK);
  168. }
  169.  
  170. /*
  171.  *    add_blk() inserts an empty new block into the work
  172.  *    file chain immediately after the current block. The
  173.  *    current block remains current. Normal return value
  174.  *    is OK; return of ERR indicates hopeless confusion in
  175.  *    VM file and abort of the run should result.
  176.  *
  177.  *    Note that there is no special treatment for the last
  178.  *    block of the file. Block 0 is both the first and the
  179.  *    last block; the file is "ring-linked". This makes it
  180.  *    easy to reach the end of file by getting Block 0 and
  181.  *    then getting its "prev" block. This is the major
  182.  *    difference between this VM system and that used in
  183.  *    Ed Ream's "RED".
  184.  */
  185. add_blk()        /* links new block after Curr one */
  186.         /* returns OK or ERR only */
  187. {    int    new,cur,nxt;    /* link values */
  188.         /* save links */
  189.     cur = Curr;
  190.     nxt = *Nxptr;
  191.     if (Free) {            /* free list not empty */
  192.         if (vm_get(Free)) return(vm_err("add_blk free"));
  193.         new = Free;
  194.         Free = *Nxptr;        /* cut it loose */
  195.         smudge();
  196.         }
  197.     else                /* must create new one */
  198.         new = Lstsec + BLKINC;
  199.     /* patch all the pointers */
  200.     if (vm_get(nxt)) return(vm_err("add_blk nxt"));
  201.     *Pvptr = new;
  202.     smudge();
  203.     /* now set up the new one. it will be created by the
  204.      * the vm_get() call, if it did not already exist.
  205.      */
  206.     if (vm_get(new)) return(vm_err("add_blk new"));
  207.     *Nxptr = nxt;
  208.     *Pvptr = cur;
  209.     *Bcptr = BHAD;
  210.     *Lcptr = 0;
  211.     smudge();
  212.     if (vm_get(cur)) return(vm_err("add_blk cur"));
  213.     *Nxptr = new;
  214.     smudge();
  215.     return (OK);
  216. }
  217.  
  218. /*
  219.  *    rel_blk() deletes the current block from the work
  220.  *    file chain and adds it to the head of the free list.
  221.  *    The block PRECEDING the current block becomes the
  222.  *    current one. Normal return value is OK; if you try
  223.  *    to release Block 0 the return value will be EOF. A
  224.  *    return value of ERR indicates the function failed to
  225.  *    complete successfully; the run should abort in this
  226.  *    case as the VM file is hopelessly confused!
  227.  */
  228. rel_blk()
  229. {    int    rel,prv,nxt;    /* links */
  230.     if (Curr) {            /* never release Block 0! */
  231.             /* save link values */
  232.         rel = Curr;
  233.         prv = *Pvptr;
  234.         nxt = *Nxptr;
  235.             /* fix backward link first */
  236.         if (vm_get(nxt)) return(vm_err("rel_blk next"));
  237.         *Pvptr = prv;
  238.         smudge();
  239.             /* then take out of chain */
  240.         if (vm_get(prv)) return(vm_err("rel_blk prev"));
  241.         *Nxptr = nxt;
  242.         smudge();
  243.             /* and put on free list */
  244.         if (vm_get(rel)) return(vm_err("rel_blk curr"));
  245.         *Nxptr = Free;
  246.         *Pvptr = ERR;        /* for debugging */
  247.         smudge();
  248.         Free = rel;        /* point Free to this one */
  249.         return(vm_get(prv));
  250.         }
  251.     else return(EOF);
  252. }
  253.  
  254.